﻿using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.VisualBasic.FileIO;

using JackProjectTemplate.Shared.CommonResult;
using JackProjectTemplate.Storage.OSS;
using JackProjectTemplate.Web.Dtos.CommonDtos;

namespace JackProjectTemplate.Web.Controllers
{
    /// <summary>
    /// 公共接口
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class CommonController(ILogger<CommonController> logger) : ControllerBase
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        [HttpPost]
        public async Task<ActionResult<DataResponse<string>>> UploadFile([FromForm, Required, NotNull] UploadFileRequest request, [FromServices, NotNull] IOSSManager ossManager)
        {
            try
            {
                IFormFile file = request.File;
                string type = request.Type;
                if (file.Length <= 0) return DataResponse<string>.CreateFailureResult("请选择要上传的文件");

                if (file.Length > 5_000_0000) return DataResponse<string>.CreateFailureResult("文件不能大于50M");

                type = type.ToLower();
                switch (type)
                {
                    case "picture":
                    case "video":
                    case "file":
                        break;
                    default: return DataResponse<string>.CreateFailureResult("文件类型不支持");
                }

                string? projectName = Assembly.GetEntryAssembly()?.GetName().Name?.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).FirstOrDefault() ?? "default";
                string fileName;

                using MemoryStream ms = new();
                await file.CopyToAsync(ms);
                ms.Seek(0, SeekOrigin.Begin);

                using (HMACMD5 md5 = new(Encoding.UTF8.GetBytes(projectName)))
                {
                    byte[] md5HashData = md5.ComputeHash(ms);
                    string md5Hash = string.Join(string.Empty, md5HashData.Select(x => x.ToString("x2")));

                    fileName = $"{md5Hash[..16]}/{projectName}/{type}/{md5Hash[16..]}{Path.GetExtension(file.FileName)}";
                }

                ms.Seek(0, SeekOrigin.Begin);
                var response = ossManager.PutObject(fileName, ms);
                if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) return DataResponse<string>.CreateFailureResult("文件保存失败");

                return DataResponse<string>.CreateSuccessResult(ossManager.BuildFullUrl(fileName));
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"上传文件失败");
                return DataResponse<string>.CreateFailureResult("上传文件失败");
            }
        }
    }
}
